package com.jdd.modules.parkmonthly.websocket;

import com.alibaba.fastjson.JSONObject;
import com.jdd.common.constant.WebSocketToAndAllEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@ServerEndpoint("/monthlyWebSocket/{token}")
@Component
public class MonthlyWebSocket {
	/** 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。 */
	private static int onlineCount = 0;
	/** concurrent包的线程安全Set，用来存放每个客户端对应的WebSocket对象。*/
	private static Map<String, MonthlyWebSocket> clients = new ConcurrentHashMap<String, MonthlyWebSocket>();
	/** 与某个客户端的连接会话，需要通过它来给客户端发送数据 */
	private Session session;
	/** 接收用户username */
	private String token;

	/** 连接建立成功调用的方法 */
	@OnOpen
	public void onOpen(@PathParam("token") String token, Session session) throws IOException {

		this.token = token;
		this.session = session;

		if(StringUtils.isNoneBlank(token)){
			addOnlineCount();
			clients.put(token, this);
		}
		log.info("有新的客户端连接了 -> {}", token);
	}

	@OnClose
	public void onClose() throws IOException {
		clients.remove(token);
		subOnlineCount();
		log.info("有用户断开了, 用户名为 -> {}", token);
	}

	/**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
	@OnMessage
	public void onMessage(String message) throws IOException {
        log.info("服务端收到客户端发来的消息: {}", message);
        JSONObject jsonTo = JSONObject.parseObject(message);
        String mes = (String) jsonTo.get("message");

        // 判断发送人群
//		if (jsonTo.get(WebSocketToAndAllEnum.TO.value()) != null &&
//				jsonTo.get(WebSocketToAndAllEnum.TO.value()).equals(this.username)) {
        sendMessageTo(mes, jsonTo.get(WebSocketToAndAllEnum.TO.value()).toString());
//		} else {
//			sendMessageAll(mes);
//		}
    }

	@OnError
	public void onError(Session session, Throwable error) {
		log.error("用户错误:"+token+",原因:"+error.getMessage());
		error.printStackTrace();
	}

	public void sendMessageTo(String message, String To) throws IOException {
		// session.getBasicRemote().sendText(message);
		// session.getAsyncRemote().sendText(message);
		for (MonthlyWebSocket item : clients.values()) {
            if (item.token.equals(To)) {
                item.session.getAsyncRemote().sendText(message);
            }
        }
	}

	public void sendMessageAll(String message) throws IOException {
		for (MonthlyWebSocket item : clients.values()) {
			item.session.getAsyncRemote().sendText(message);
		}
	}

	public static synchronized int getOnlineCount() {
		return onlineCount;
	}

	public static synchronized void addOnlineCount() {
		MonthlyWebSocket.onlineCount++;
	}

	public static synchronized void subOnlineCount() {
		MonthlyWebSocket.onlineCount--;
	}

	public static synchronized Map<String, MonthlyWebSocket> getClients() {
		return clients;
	}
}
